import React, { createContext, useContext, useReducer, useCallback } from 'react';
import { AppState, AppContextType } from './types';
import NetInfo from '@react-native-community/netinfo';

// 初始状态
const initialState: AppState = {
  isLoading: false,
  error: null,
  networkStatus: 'online',
  lastSync: null,
};

// 创建上下文
const AppContext = createContext<AppContextType | undefined>(undefined);

// Action 类型
type AppAction =
  | { type: 'SET_LOADING'; payload: boolean }
  | { type: 'SET_ERROR'; payload: string | null }
  | { type: 'SET_NETWORK_STATUS'; payload: 'online' | 'offline' }
  | { type: 'SET_LAST_SYNC'; payload: string }
  | { type: 'CLEAR_ERROR' };

// Reducer
function appReducer(state: AppState, action: AppAction): AppState {
  switch (action.type) {
    case 'SET_LOADING':
      return {
        ...state,
        isLoading: action.payload,
      };
    case 'SET_ERROR':
      return {
        ...state,
        error: action.payload,
      };
    case 'SET_NETWORK_STATUS':
      return {
        ...state,
        networkStatus: action.payload,
      };
    case 'SET_LAST_SYNC':
      return {
        ...state,
        lastSync: action.payload,
      };
    case 'CLEAR_ERROR':
      return {
        ...state,
        error: null,
      };
    default:
      return state;
  }
}

// Provider 组件
export function AppProvider({ children }: { children: React.ReactNode }) {
  const [state, dispatch] = useReducer(appReducer, initialState);

  // 监听网络状态
  React.useEffect(() => {
    const unsubscribe = NetInfo.addEventListener(state => {
      dispatch({
        type: 'SET_NETWORK_STATUS',
        payload: state.isConnected ? 'online' : 'offline',
      });
    });

    return () => unsubscribe();
  }, []);

  const setLoading = useCallback((loading: boolean) => {
    dispatch({ type: 'SET_LOADING', payload: loading });
  }, []);

  const setError = useCallback((error: string | null) => {
    dispatch({ type: 'SET_ERROR', payload: error });
  }, []);

  const setNetworkStatus = useCallback((status: 'online' | 'offline') => {
    dispatch({ type: 'SET_NETWORK_STATUS', payload: status });
  }, []);

  const setLastSync = useCallback((date: string) => {
    dispatch({ type: 'SET_LAST_SYNC', payload: date });
  }, []);

  const clearError = useCallback(() => {
    dispatch({ type: 'CLEAR_ERROR' });
  }, []);

  const value = {
    ...state,
    setLoading,
    setError,
    setNetworkStatus,
    setLastSync,
    clearError,
  };

  return <AppContext.Provider value={value}>{children}</AppContext.Provider>;
}

// Hook
export function useApp() {
  const context = useContext(AppContext);
  if (context === undefined) {
    throw new Error('useApp must be used within an AppProvider');
  }
  return context;
} 